package v2ray

import (
	"gitee.com/Luna-CY/hui-hui/internal/interface/application"
	"gitee.com/Luna-CY/hui-hui/internal/util/data"
	"gitee.com/Luna-CY/hui-hui/internal/util/point"
)

func New(v2ray application.V2ray) *V2ray {
	return &V2ray{v2ray: v2ray}
}

type V2ray struct {
	v2ray application.V2ray
}

type BaseBoundRequest struct {
	Id  string `json:"id" validate:"optional" binding:"omitempty,uuid"` // 配置ID，可以为空
	Tag string `json:"tag" validate:"optional" binding:"omitempty"`     // 配置标签，可以为空，否则在V2ray配置中唯一
}

type BaseInboundRequest struct {
	InboundListen string `json:"inbound_listen" validate:"required" binding:"required,ip"`            // 监听地址
	InboundPort   int    `json:"inbound_port" validate:"required" binding:"required,min=1,max=65535"` // 监听端口
}

type BaseOutboundRequest struct {
	OutboundSendThrough string `json:"outbound_send_through" validate:"optional" binding:"omitempty,ip"` // 用于发送数据的IP地址，默认为0.0.0.0
}

type BaseStreamSettingsRequest struct {
	Enable      bool   `json:"enable" validate:"optional" binding:"omitempty"` // 是否启用传输配置
	Network     string `json:"network" validate:"optional" enums:"tcp,kcp,ws,domainsocket,http,quic" binding:"omitempty,oneof=tcp kcp ws domainsocket http quic"`
	TlsSettings struct {
		ClientOnly bool   `json:"client_only" validate:"optional" binding:"omitempty"`                              // 是否仅客户端有效
		Security   string `json:"security" validate:"optional" enums:"none,tls" binding:"omitempty,oneof=none tls"` // 安全类型，none或tls
		ServerName string `json:"server_name" validate:"optional" binding:"omitempty"`                              // TLS域名
	} `json:"tls_settings" validate:"optional" binding:"omitempty"`
	TcpSettings struct {
		Header struct {
			Type string `json:"type" validate:"optional" binding:"omitempty"` // 默认为none
		} `json:"header" validate:"optional" binding:"omitempty"`
	} `json:"tcp_settings" validate:"optional" binding:"omitempty"`
	KcpSettings struct {
		Mtu              int  `json:"mtu" validate:"optional" minimum:"576" maximum:"1460" binding:"omitempty,min=576,max=1460"` // 传输单元配置，允许的范围为576-1460，默认为1350
		Tti              int  `json:"tti" validate:"optional" minimum:"1" maximum:"100" binding:"omitempty,min=1,max=100"`       // 传输频率，允许的范围为1-100，默认为50
		UplinkCapacity   *int `json:"uplink_capacity" validate:"optional" minimum:"0" binding:"omitempty,min=0"`                 // 上行带宽限制，单位MB，默认值为5，允许设置为0
		DownlinkCapacity *int `json:"downlink_capacity" validate:"optional" minimum:"0" binding:"omitempty,min=0"`               // 下行带宽限制，单位MB，默认值为20，允许设置为0
		Congestion       bool `json:"congestion" validate:"optional" binding:"omitempty"`                                        // 是否启用拥塞控制
		ReadBufferSize   int  `json:"read_buffer_size" validate:"optional" binding:"omitempty"`                                  // 单个连接的读缓冲区大小，单位MB，默认为2
		WriteBufferSize  int  `json:"write_buffer_size" validate:"optional" binding:"omitempty"`                                 // 单个连接的写缓冲区大小，单位MB，默认为2
		Header           struct {
			Type string `json:"type" validate:"optional" enums:"none,srtp,utp,wechat-video,dtls,wireguard" binding:"omitempty,oneof=none srtp utp wechat-video dtls wireguard"` // 伪装类型，默认为none，可选: none/srtp/utp/wechat-video/dtls/wireguard
		} `json:"header" validate:"optional" binding:"omitempty"` // 头信息配置
	} `json:"kcp_settings" validate:"optional" binding:"omitempty"`
	WebsocketSettings struct {
		Path    string            `json:"path" validate:"optional" binding:"omitempty"`    // 默认值为/
		Headers map[string]string `json:"headers" validate:"optional" binding:"omitempty"` // 头信息，KEY/VALUE对
	} `json:"websocket_settings" validate:"optional" binding:"omitempty"`
	DomainSocketSettings struct {
		Path string `json:"path" validate:"optional" binding:"omitempty"` // 一个文件路径，V2ray启动前，此文件必须不存在，但路径必须有效(文件夹有效)
	} `json:"domain_socket_settings" validate:"optional" binding:"omitempty"`
	Http2Settings struct {
		Host []string `json:"host" validate:"optional" binding:"omitempty"`
		Path string   `json:"path" validate:"optional" binding:"omitempty"` // 默认值为/
	} `json:"http2_settings" validate:"optional" binding:"omitempty"`
	QuicSettings struct {
		Security string `json:"security" validate:"optional" enums:"none,aes-128-gcm,chacha20-poly1305" binding:"omitempty,oneof=none aes-128-gcm chacha20-poly1305"` // 加密类型，默认为none，可选: none/aes-128-gcm/chacha20-poly1305
		Key      string `json:"key" validate:"optional" binding:"required_unless=Security none,omitempty"`                                                            // 加密类型不为none时用于加密数据
		Header   struct {
			Type string `json:"type" validate:"optional" enums:"none,srtp,utp,wechat-video,dtls,wireguard" binding:"omitempty,oneof=none srtp utp wechat-video dtls wireguard"` // 伪装类型，默认为none，可选: none/srtp/utp/wechat-video/dtls/wireguard
		} `json:"header" validate:"optional" binding:"omitempty"` // 头信息配置
	} `json:"quic_settings" validate:"optional" binding:"omitempty"`
}

// build 构建V2ray的传输配置对象
func (cls *BaseStreamSettingsRequest) build() *application.V2rayStreamSettings {
	var stream = new(application.V2rayStreamSettings)

	stream.Enable = cls.Enable
	stream.Network = data.Default(application.V2rayStreamSettingsNetwork(cls.Network), application.V2rayStreamSettingsNetworkTcp)
	stream.TlsSettings.ClientOnly = cls.TlsSettings.ClientOnly
	stream.TlsSettings.Security = data.Default(cls.TlsSettings.Security, "none")
	stream.TlsSettings.ServerName = cls.TlsSettings.ServerName

	// tcp
	stream.TcpSettings.Header.Type = data.Default(cls.TcpSettings.Header.Type, "none")

	// kcp
	stream.KcpSettings.Mtu = cls.KcpSettings.Mtu
	stream.KcpSettings.Tti = cls.KcpSettings.Tti
	stream.KcpSettings.ReadBufferSize = data.Default(cls.KcpSettings.ReadBufferSize, 2)
	stream.KcpSettings.WriteBufferSize = data.Default(cls.KcpSettings.WriteBufferSize, 2)
	stream.KcpSettings.UplinkCapacity = data.Default(cls.KcpSettings.UplinkCapacity, point.New(5))
	stream.KcpSettings.DownlinkCapacity = data.Default(cls.KcpSettings.DownlinkCapacity, point.New(20))
	stream.KcpSettings.Congestion = cls.KcpSettings.Congestion
	stream.KcpSettings.Header.Type = data.Default(cls.KcpSettings.Header.Type, "none")

	// websocket
	stream.WebsocketSettings.Path = data.Default(cls.WebsocketSettings.Path, "/")
	stream.WebsocketSettings.Headers = cls.WebsocketSettings.Headers

	// domain socket
	stream.DomainSocketSettings.Path = cls.DomainSocketSettings.Path

	// http
	stream.Http2Settings.Host = cls.Http2Settings.Host
	stream.Http2Settings.Path = cls.Http2Settings.Path

	// quic
	stream.QuicSettings.Security = data.Default(cls.QuicSettings.Security, "none")
	stream.QuicSettings.Key = cls.QuicSettings.Key
	stream.QuicSettings.Header.Type = data.Default(cls.QuicSettings.Header.Type, "none")

	return stream
}
